A Brief Discussion on Synchronizing Entity Framework Navigation Properties and Foreign Keys
TLDR
- The prerequisite for navigation property synchronization is that the relevant entities must be in a tracked state.
- Any operation that causes an entity's state to change (such as
Add,Remove, or callingEntry()) will trigger a tracking check, which in turn automatically synchronizes navigation properties. - Whether navigation properties are synchronized in real-time does not affect the execution result of
SaveChanges(); EF Core automatically performs change detection and completes synchronization during the save process. - If you only set the Foreign Key property without triggering a tracking check, the navigation property will not be updated immediately.
- When removing a relationship, using
main.Subs.Remove(sub)only breaks the association (or deletes the many-to-many relationship record). To delete the child record, you must explicitly callcontext.Subs.Remove(sub).
Entity Structure Definition
This test is based on Entity Framework Core 8, defining the relationship between the parent table Main and the child table Sub.
public partial class Main {
public long Id { get; set; }
public virtual ICollection<Sub> Subs { get; set; } = new List<Sub>();
}
public partial class Sub {
public long Id { get; set; }
public long MainId { get; set; }
public virtual Main Main { get; set; }
}The Relationship Between Navigation Properties and Tracking State
Scenario: When do navigation properties synchronize automatically?
In development, developers often wonder whether modifying Main.Subs or Sub.Main will cause the property on the other end to update immediately.
- Detached State: If an entity is in the
Detachedstate, modifying navigation properties will not trigger any synchronization. - Single-Sided Tracking: If only the parent table is tracked, adding a child to
Main.Subswill automatically add the child to tracking and synchronize the navigation property; conversely, if only the child is tracked, settingSub.Mainwill cause the parent to be synchronized and added to tracking. - Triggering Checks: When calling
context.Entry(entity)or executingSaveChanges(), EF Core forces a state check, at which point navigation properties are automatically corrected to the correct state.
TIP
Even if SaveChanges() fails (e.g., due to a primary key conflict), EF Core will still complete the synchronization of navigation properties.
Synchronization Behavior of Foreign Key Properties and Navigation Properties
Scenario: Does directly modifying a Foreign Key property update the navigation property?
When a developer assigns a value directly, such as sub.MainId = 1L, if the entity is not yet tracked or a check has not been triggered, the navigation property sub.Main will not immediately point to the corresponding object.
- Modification After Tracking: If
subandmainare already tracked, modifyingsub.MainIddirectly will not immediately update thesub.Mainobject reference. - Synchronization Mechanism: This behavior is automatically corrected by the EF Core Change Tracker after calling
SaveChanges()orEntry(). - Impact of the Find Method: When retrieving data using
context.Mains.Find(id), if the parent table already exists in the tracker, EF Core will automatically associate it with the existing child records.
Differences Between Removing Relationships and Deleting Data
Scenario: How to correctly remove a relationship or delete data?
Developers often confuse "breaking an association" with "deleting data."
- Deleting Data: You must explicitly call
context.Subs.Remove(sub), which marks the entity asDeletedand removes it from the database uponSaveChanges(). - Breaking an Association: Using
main.Subs.Remove(sub)only breaks the relationship between the two.- If the foreign key property allows
null, the foreign key will be set tonull. - If it is a many-to-many relationship, only the association record in the join table will be deleted; the entity itself will not be deleted.
- If the foreign key property allows
Conclusion
- Tracking and Synchronization: The prerequisite for navigation property synchronization is that entities on both sides must be in a tracked state. Any operation that causes an entity's state to change will trigger a tracking state check, thereby automatically synchronizing and updating navigation properties.
- Database Updates: Whether navigation properties are synchronized does not affect the actual database update. Even if navigation properties are not synchronized, when
SaveChanges()is executed, the system will perform an entity change tracking check and automatically trigger the synchronization of navigation properties. - Foreign Key Participation: When an entity triggers a change tracking check, foreign key properties also participate in the synchronization process, so foreign key properties can be used to influence the values of navigation properties.
- Data Retrieval Impact: When data is read from the database and added to tracking, the navigation properties of related local entities will be automatically synchronized and updated.
Change Log
- 2024-08-12 Initial version created.
